package fairygui.editor.publish
{
   import fairygui.editor.Consts;
   import fairygui.editor.gui.EUIPackage;
   import fairygui.editor.gui.EUIProject;
   import fairygui.editor.publish.exporter.EgretExporter;
   import fairygui.editor.publish.exporter.FlashExporter;
   import fairygui.editor.publish.exporter.LayaExporter;
   import fairygui.editor.publish.exporter.StarlingExporter;
   import fairygui.editor.publish.exporter.UnityExporter;
   import fairygui.editor.publish.gencode.GenAS3;
   import fairygui.editor.publish.gencode.GenCSharp;
   import fairygui.editor.publish.gencode.GenHaxe;
   import fairygui.editor.publish.gencode.GenTypeScript;
   import fairygui.editor.settings.GlobalPublishSettings;
   import fairygui.editor.settings.PublishSettings;
   import fairygui.editor.utils.Callback;
   import fairygui.editor.utils.RuntimeErrorUtil;
   import fairygui.editor.utils.UtilsStr;
   import flash.filesystem.File;
   
   public class PublishHandler
   {
       
      
      private var _data:PublishData;
      
      private var _callback:Callback;
      
      private var _currentStep:PublishStep;
      
      private var _stepCallback:Callback;
      
      public function PublishHandler()
      {
         super();
      }
      
      public function publish(param1:EUIPackage, param2:Boolean, param3:String, param4:Callback) : void
      {
         var path:String = null;
         var targetFolder:File = null;
         var targetFile:File = null;
         var pkg:EUIPackage = param1;
         var exportDescOnly:Boolean = param2;
         var targetPath:String = param3;
         var callback:Callback = param4;
         pkg.ensureOpen();
         var settings:PublishSettings = pkg.publishSettings;
         var gsettings:GlobalPublishSettings = pkg.project.settingsCenter.publish;
         if(!settings.filePath && !pkg.project.settingsCenter.publish.filePath && !targetPath)
         {
            callback.addMsg(UtilsStr.formatString(Consts.g.text100,pkg.name));
            callback.callOnFail();
            return;
         }
         if(!settings.fileName)
         {
            callback.addMsg(UtilsStr.formatString(Consts.g.text101,pkg.name));
            callback.callOnFail();
            return;
         }
         this._callback = callback;
         this._data = new PublishData();
         this._data.pkg = pkg;
         this._data._project = pkg.project;
         try
         {
            if(targetPath)
            {
               path = targetPath;
            }
            else if(settings.filePath)
            {
               path = settings.filePath;
            }
            else
            {
               path = this._data._project.settingsCenter.publish.filePath;
            }
            if(path.indexOf("{") != -1)
            {
               path = UtilsStr.formatStringByName(path,{"publish_file_name":settings.fileName});
               path = UtilsStr.formatStringByName(path,pkg.project.customProperties);
            }
            targetFolder = new File(pkg.project.basePath).resolvePath(path);
            targetFile = targetFolder.resolvePath(settings.fileName);
            targetFolder = targetFile.parent;
            if(!targetFolder.exists)
            {
               targetFolder.createDirectory();
            }
            else if(!targetFolder.isDirectory)
            {
               this._callback.addMsg(Consts.g.text327);
               this._callback.callOnFail();
               return;
            }
            this._data._filePath = targetFolder.nativePath;
            this._callback.result = this._data._filePath;
         }
         catch(err:Error)
         {
            _callback.addMsg(Consts.g.text327);
            _callback.callOnFail();
            return;
         }
         var ext:String = targetFile.extension;
         this._data._fileName = UtilsStr.getFileName(targetFile.name);
         if(this._data._project.type == EUIProject.TYPE_UNITY)
         {
            this._data._fileExtension = "bytes";
         }
         else if(ext)
         {
            this._data._fileExtension = ext;
         }
         else if(!gsettings.fileExtension)
         {
            if(this._data._project.type == EUIProject.TYPE_EGRET || this._data._project.type == EUIProject.TYPE_LAYABOX)
            {
               this._data._fileExtension = "fui";
            }
            else
            {
               this._data._fileExtension = "zip";
            }
         }
         else
         {
            this._data._fileExtension = gsettings.fileExtension;
         }
         this._data._exportDescOnly = exportDescOnly;
         this._data._singlePackage = settings.packageCount == 1 || settings.packageCount == 0 && gsettings.packageCount == 1;
         if(pkg.project.type == EUIProject.TYPE_FLASH || pkg.project.type == EUIProject.TYPE_STARLING || EUIProject.TYPE_HAXE)
         {
            if(this._data._singlePackage)
            {
               this._data._exportDescOnly = false;
            }
         }
         this._data._extractAlpha = pkg.project.type == EUIProject.TYPE_UNITY && settings.atlasList[0].extractAlpha;
         this._data.usingAtlas = pkg.project.usingAtlas;
         this._data._genCode = settings.genCode;
         this._stepCallback = new Callback();
         this._stepCallback.failed = this.handleCallbackErrors;
         this.runStep(new CollectItems(),this.handleImages);
      }
      
      private function handleImages() : void
      {
         this._data.pkg.publishing = true;
         this._callback.result2 = CollectItems(this._currentStep).excludedCount;
         if(this._data.usingAtlas)
         {
            this.runStep(new CreateBins(),this.createOutput);
         }
         else
         {
            this.runStep(new HandleImages(),this.createOutput);
         }
      }
      
      private function createOutput() : void
      {
         this.runStep(new CreateOutput(),this.callPlugins);
      }
      
      private function callPlugins() : void
      {
         this.runStep(new CallPlugins(),!!this._data._genCode?this.generateCode:this.export);
      }
      
      private function generateCode() : void
      {
         var _loc1_:PublishStep = null;
         if(!this._data._project.settingsCenter.publish.codePath)
         {
            this._callback.addMsg(Consts.g.text273);
            this.export();
            return;
         }
         if(this._data._project.settingsCenter.publish.codeType)
         {
            switch(this._data._project.settingsCenter.publish.codeType)
            {
               case "AS3":
                  _loc1_ = new GenAS3();
                  break;
               case "TS":
                  _loc1_ = new GenTypeScript();
                  break;
               case "C#":
                  _loc1_ = new GenCSharp();
                  break;
               case "HAXE":
                  _loc1_ = new GenHaxe();
            }
         }
         else
         {
            switch(this._data._project.type)
            {
               case EUIProject.TYPE_FLASH:
               case EUIProject.TYPE_STARLING:
               case EUIProject.TYPE_LAYABOX:
                  _loc1_ = new GenAS3();
                  break;
               case EUIProject.TYPE_EGRET:
                  _loc1_ = new GenTypeScript();
               case EUIProject.TYPE_UNITY:
                  _loc1_ = new GenCSharp();
                  break;
               case EUIProject.TYPE_HAXE:
                  _loc1_ = new GenHaxe();
            }
         }
         if(_loc1_)
         {
            this.runStep(_loc1_,this.export);
         }
         else
         {
            this._callback.addMsg("unkown code type");
            this.export();
         }
      }
      
      private function export() : void
      {
         var _loc1_:PublishStep = null;
         switch(this._data._project.type)
         {
            case EUIProject.TYPE_HAXE:
            case EUIProject.TYPE_FLASH:
               _loc1_ = new FlashExporter();
               break;
            case EUIProject.TYPE_STARLING:
               _loc1_ = new StarlingExporter();
               break;
            case EUIProject.TYPE_EGRET:
               _loc1_ = new EgretExporter();
               break;
            case EUIProject.TYPE_LAYABOX:
               _loc1_ = new LayaExporter();
               break;
            case EUIProject.TYPE_UNITY:
               _loc1_ = new UnityExporter();
         }
         this.runStep(_loc1_,this.publishCompleted);
      }
      
      private function runStep(param1:PublishStep, param2:Function) : void
      {
         var step:PublishStep = param1;
         var next:Function = param2;
         this._currentStep = step;
         try
         {
            this._stepCallback.success = next;
            this._currentStep.publishData = this._data;
            this._currentStep.stepCallback = this._stepCallback;
            this._callback.addMsgs(this._stepCallback.msgs);
            this._stepCallback.msgs.length = 0;
            this._currentStep.run();
            if(this._data._defaultPrevented)
            {
               this.publishCompleted();
            }
            return;
         }
         catch(err:Error)
         {
            handleException(err);
            return;
         }
      }
      
      private function publishCompleted() : void
      {
         this._data.pkg.publishing = false;
         this._currentStep = null;
         this._callback.callOnSuccess();
      }
      
      private function handleCallbackErrors() : void
      {
         this._data.pkg.publishing = false;
         this._currentStep = null;
         this._callback.msgs.length = 0;
         this._callback.addMsgs(this._stepCallback.msgs);
         this._callback.callOnFail();
      }
      
      private function handleException(param1:Error) : void
      {
         this._data.pkg.publishing = false;
         this._currentStep = null;
         this._callback.msgs.length = 0;
         if(param1.errorID == 3013)
         {
            this._callback.addMsg(Consts.g.text123);
         }
         else if(param1.errorID == 3003)
         {
            this._callback.addMsg("target folder not exists!");
         }
         else
         {
            this._callback.addMsg(RuntimeErrorUtil.toString(param1));
         }
         this._callback.callOnFail();
      }
   }
}
